package MVC.view.returnframe;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeNode;

import org.jdesktop.swingx.JXTitledPanel;
import org.jdesktop.swingx.border.DropShadowBorder;

import test.methodResult;
import MVC.view.MyTreeModel;
import MVC.view.MyTreeNode;


public class ReturnFrame extends JFrame implements ActionListener, TreeSelectionListener{

	/**
	 * A table presenting the results
	 */
	private JTable table = null;
	
	/**
	 * A tree presenting the model. Permits to explore methods that had been checked.
	 */
	private JTree tree = null;
	
	/**
	 * The Quit button
	 */
	private JButton quit = null;
	
	/**
	 * The container of the frame
	 */
	private JPanel container = null;
	
	/**
	 * The column names of the Table
	 */
	private final String[] tableColumnNames = {"Error Type","Line(s)"};
	
	/**
	 * The model used by the Tree
	 */
	private MyTreeModel treeModel = null;
	
	
	/**
	 * @param title the title of the frame
	 * @param model the general model of jars, packages, classes and methods.
	 * @throws HeadlessException
	 * 
	 * Constructs a ReturnFrame
	 */
	public ReturnFrame(String title, MyTreeModel model) throws HeadlessException {
		super(title);
		hideNodes(model);
		this.treeModel = model;
		this.treeModel.setShowAll(false);
		buildReturnFrame();
	}


	/**
	 * @param model
	 * 
	 * Update the general node model and hides the node that haven't been checked yet. Colors the nodes with errors in red. 
	 */
	private void hideNodes(MyTreeModel model) {
		MyTreeNode leaf = (MyTreeNode) ((MyTreeNode) model.getRoot()).getFirstLeaf();
		while (leaf != null){
			if (model.getmR().containsKey(leaf.getVersion())){
				if (model.getmR().get(leaf.getVersion()).size() != 0 ){
					boolean error = false;
					for (int i = 0;i<model.getmR().get(leaf.getVersion()).size();i++){
						if (model.getmR().get(leaf.getVersion()).get(i).getLigne().size() != 0)
							error = true;
					}
					if (error)
						leaf.setHasError(true);
				}
				if (leaf.isHasError()){
					TreeNode[] nodes = leaf.getPath();
					for (int i = 0;i<nodes.length ; i++){
						((MyTreeNode)nodes[i]).setChecked(true);
						((MyTreeNode)nodes[i]).setHasError(true);
					}
				}
				else{
					TreeNode[] nodes = leaf.getPath();
					for (int i = 0;i<nodes.length ; i++){
						((MyTreeNode)nodes[i]).setChecked(true);
					}
				}
			}
			leaf = (MyTreeNode) leaf.getNextLeaf();
		}
	}


	/**
	 * Build the frame presenting the results
	 * 
	 */
	public void buildReturnFrame(){
		this.setTitle("Results");
		this.setSize(850, 450);
		this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		this.setLocationRelativeTo(null);
		this.setResizable(false);
		
		this.tree = new JTree(this.treeModel);
		this.tree.addTreeSelectionListener(this);
		this.tree.setRootVisible(false);
		this.tree.setCellRenderer(new MyTreeCellRenderer());
		this.table = getJTable();
		this.quit = new JButton("Close");
		this.container = new JPanel();


		this.quit.addActionListener(this);
		
		JScrollPane treePanel = new JScrollPane(this.tree);
		treePanel.setPreferredSize(new Dimension(400,310));
		
		JScrollPane tablePanel = new JScrollPane(this.table);
		tablePanel.setPreferredSize(new Dimension(400,310));
		
		JPanel generalPanel = new JPanel();
		generalPanel.add(treePanel,BorderLayout.WEST);
		generalPanel.add(tablePanel,BorderLayout.EAST);
		generalPanel.add(this.quit,BorderLayout.SOUTH);
		
		
		JXTitledPanel results = new JXTitledPanel("Results");
		results.setBorder(new DropShadowBorder());
		results.setPreferredSize(new Dimension(830,410));
		results.add(generalPanel);
		container.setBackground(Color.white);
	    container.add(results);
		
		
	    this.setContentPane(container);
		this.setVisible(true);
	}


	private JTable getJTable() {
        if (table == null) {
            table = new JTable();
            Object[][] data= {{},{}};
            MyTableModel myTabModel = new MyTableModel(data,this.tableColumnNames);
            table.setModel(myTabModel);
        }
        return table;
    }
	
	
	@Override
	public void actionPerformed(ActionEvent arg0) {
		Object source = arg0.getSource();
        if (source.equals(quit)){
        	this.dispose();
        }
	}


	@Override
	public void valueChanged(TreeSelectionEvent arg0) {
		MyTreeNode node = (MyTreeNode) arg0.getNewLeadSelectionPath().getLastPathComponent();
		if ( node.isLeaf() ){
			drawTable(node);
		}
	}


	/**
	 * @param node : the node we want the results for.
	 * 
	 * Called when the user clicks on a leaf. Draw the corresponding results table.
	 */
	private void drawTable(MyTreeNode node) {
		Object[][] data= {{null},{null}};
		if (node == null){
			((MyTableModel)this.table.getModel()).changeData(data);
		}
		else{
			data = fillData(node);
			((MyTableModel)this.table.getModel()).changeData(data);
		}	
	}


	/**
	 * @param node : the node we want the results for.
	 * @return an Object array containing data to fill the table presenting the results.
	 */
	private Object[][] fillData(MyTreeNode node) {
		Integer id = node.getVersion();
		ArrayList<methodResult> mR = this.treeModel.getmR().get(id);
 		Object[][] data = new Object[mR.size()][2];
 		for (int i=0;i<mR.size();i++){
 			data[i][0] = mR.get(i).getType();
 			data[i][1] = mR.get(i).printLines();
 		}
		return data;
	}
	
	
}
